if (typeof Mirando == "undefined") {
    var Mirando = function() {};
}

if (typeof Mirando.instanceRegistry == "undefined") {

	(function() {    
		function InstanceRegistry() {

			var me = this;
			var instances = {};

			this.getNextInstanceIdFor = function(adPlaceId)  {

				if ( !instances[adPlaceId] ) {
					instances[adPlaceId] = 1;
				}
				else {
					instances[adPlaceId]++;
				}
				
				return instances[adPlaceId];
			};

		}
		
		Mirando.instanceRegistry = new InstanceRegistry();
	})();
}

if (typeof Mirando.log == "undefined") {

        (function() {
            var MirLog = function() {

                var entries = [];

                this.out = function(msg) {
                    entries.push(msg);
                };

                this.dump = function() {
                    if (typeof console == "undefined" || typeof console.info == "undefined") {
                        alert(entries.join('\n'));
                    }
                    else {
                        for (var i = 0; i < entries.length; i++) {
                            console.info(entries[i]);
                        }
                    }
                    entries = [];
                };
            };
            Mirando.log = new MirLog();
        }());
}


Mirando.ImpressionIdFactory = function() {

	var uuIdFactory  = new Mirando.UuIdFactory();

	/**
	* generates or creates an impressionId
	*/
	this.getOrCreate = function() {
		
		var result = load();
		if (!result) {
			result = createNew();
			save(result);
		}
		
		return result;
	};
	
	function createNew() {
		return uuIdFactory.create();
	}
	
	function load() {
		var id = getParentWindow().mirImpId;
		if (id) {
			return uuIdFactory.parse(id);
		}
	}
	
	function save(impId) {
		getParentWindow().mirImpId = impId.toString();
	}
	
	function getParentWindow() {
	
		var win, depth, maxDepth=10;

		do {
 			win = window.parent;
			depth++;
		} 
		while (win.parent != win && depth < maxDepth);

		
		return win;
	}
	
	var that = this;
}

Mirando.UuIdFactory = function(){

	var uuidPattern = new RegExp(/^[a-z0-9]{8}\-[a-z0-9]{4}\-[a-z0-9]{4}\-[a-z0-9]{4}\-[a-z0-9]{12}$/);

	var hexDigits = '0123456789abcdef';
	var pattern = "########-####-####-####-############";


	/**
	* Represents a simplified UUID (which does by far not meet the 
	* requirements according to rfc4122)
	*/
	var UuId = function(uuid) {
		this.toString = function() {
			return uuid;
		}
	}

	this.create = function(){

		var result = [];
		for (var i = 0; i < pattern.length; i++) {
			
			var c = pattern.charAt(i);
			
			if (c == '#') {
				result.push(randomDigit());
			}
			else {
				result.push(c);
			}
		}
		return new UuId(result.join(''));
	}
	
	this.parse = function(uuidAsString){

		if (uuidPattern.exec(uuidAsString) == null) {
			throw 'Invalid UuId: ' + uuidAsString;			
		}

		return new UuId(uuidAsString);
	}

	function randomDigit() {
		return hexDigits.charAt([Math.floor(Math.random() * 16)]);
	}
}


Mirando.QueryStringParser = function() {
	
	var queryStringPattern = new RegExp(/(\?|#)(.*)/);
	
	var params = parse();
	var queryString;
	
	this.get = function(name) {
		return params[name];
	}
	
	this.toString = function() {
		var result = []
		for (var i in params) {
			if(typeof params[i] != 'function' && typeof params[i] != 'object'){
				result.push(i + "=" + params[i]);
			}
		}
		return result.join('&');
	}

	function getLastMirandoScriptInsert(){
	
		var scripts = document.getElementsByTagName('script');
		var myScript = null;

		var regexp = new RegExp('mirando\.js');
		
		for(var i = scripts.length; i > 0; i--){
			if(regexp.exec(scripts[i-1].src)){
				myScript = scripts[i-1];
				break;
			}
		}


		return myScript;
	
	}
	
	function parse() {

		var result = [];

		var groups = queryStringPattern.exec(getLastMirandoScriptInsert().src);

		if (!groups) {
		    return result;
		}


		if (groups.length == 3) {

			var queryString = groups[2];
			var pairs = queryString.split(/[;&]/);

			for ( var i = 0; i < pairs.length; i++ ) {

				var keyVal = pairs[i].split('=');

				if ( keyVal && keyVal.length == 2 ) {
					var key = unescape( keyVal[0] );
					var val = unescape( keyVal[1] );
					result[key] = val;
				}
			}
		}
		return result;
	}
}


/**
* Renders an RepositoryRequest, that is issued via javascript
*/
Mirando.AdRequest = function(adPlaceId, impressionId, instanceId, queryString) {
	
	var that = this;

	// var urlPattern = 'http://get.mirando.de/repository/%{adPlaceId}/%{impressionId}/?%{queryString}';
	var urlPattern = 'http://get.mirando.de/repository/%{adPlaceId}/%{impressionId}/%{instanceId}/?%{queryString}';
	
	var jsIncludePattern = '[script type="text/javascript" src="%{url}"][/script]'.replace(/\[/g, '<').replace(/\]/g, '>');

	this.render = function() {
		return renderJsInclude( that.getRequestUrl() );
	}

	this.getRequestUrl = function() {
		return renderRequestUrl(adPlaceId, impressionId, queryString);
	}

	function renderJsInclude(url) {
		return jsIncludePattern.replace('%{url}', url);
	}

	function renderRequestUrl(adPlaceId, impressionId, queryString) {
		return urlPattern.replace('%{adPlaceId}', adPlaceId).replace('%{impressionId}', impressionId).replace('%{queryString}', queryString).replace('%{instanceId}', instanceId);
	}
	
}

/**
* display an ad in place
*/
Mirando.showAd = function() {
	
	var qsParser = new Mirando.QueryStringParser();
	var adPlaceId = qsParser.get('a');

	if (adPlaceId) {
		var impressionId = new Mirando.ImpressionIdFactory().getOrCreate();
		var queryString = new Mirando.QueryStringParser().toString();
		var instanceId = Mirando.instanceRegistry.getNextInstanceIdFor(adPlaceId);
		
		var request = new Mirando.AdRequest( adPlaceId, impressionId.toString(), instanceId, queryString );
	
		document.write(request.render());
	}
	else {
		Mirando.log.out('unable to obtain adPlaceId from queryString');
	} 

}

Mirando.showAd();


/* temp function */
/*
var mir_fp_available = false;
if(!mir_fp_available) {
	document.write('<iframe src="http://get.mirando.de/download/_fp_/index.php" height="10" width="10" frameborder="0" style="z-index:9999;position:absolute;visibility:none;width:10px;height:10px" name="fp_'+Math.floor(10001*Math.random())+'"></iframe>');
	mir_fp_available = true;
}
*/
